package com.mimo.logic.message.controller;

import java.util.List;
import java.util.stream.Collectors;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.mimo.common.configuration.security.rbac.annotation.AccessFor;
import com.mimo.common.logic.code.StatusCode;
import com.mimo.common.logic.dto.msg.P2PMessage;
import com.mimo.common.logic.dto.msg.Peer2RoomMessage;
import com.mimo.common.result.BaseResult;
import com.mimo.common.result.CollectionResult;
import com.mimo.common.utils.RandomStringUtils;
import com.mimo.logic.message.dto.FailedReasonDTO;
import com.mimo.logic.message.dto.SendMessageDTO;
import com.mimo.logic.message.service.IMessageDispatcher;

import io.swagger.annotations.ApiOperation;

/**
 * 用于暴露给外部的s2s消息，主要是为了方便拆分不同的消息类型，同时，增加批量的概念
 * 
 * @author Hongyu
 */
@Validated
@RestController
@RequestMapping("/message/s2s")
public class MessageS2SController {

  @Autowired
  private IMessageDispatcher messageService;

  @AccessFor
  @PostMapping(value = "/room")
  @ApiOperation(value = "房间消息分发", response = FailedReasonDTO.class)
  public BaseResult roomMessage(@Valid @RequestBody SendMessageDTO msg) {
    List<FailedReasonDTO> reasons = msg.getTargets().stream().map(target -> {
      Peer2RoomMessage pm = new Peer2RoomMessage();
      pm.setId(RandomStringUtils.uniqueRandom());
      pm.setFrom(msg.getFrom());
      pm.setTarget(target);
      pm.setContent(msg.getContent());
      return pm;
    }).map(p -> {
      StatusCode code = messageService.dispatch(p);
      FailedReasonDTO dto = new FailedReasonDTO();
      dto.setKey(p.getTarget());
      dto.setDetail(code.toBaseResult());
      return dto;
    }).filter(r -> !r.getDetail().isSuccess()).collect(Collectors.toList());

    return new CollectionResult<>(reasons);
  }

  @AccessFor
  @PostMapping(value = "/p2p")
  @ApiOperation(value = "P2P消息分发", response = FailedReasonDTO.class)
  public BaseResult p2pMessage(@Valid @RequestBody SendMessageDTO msg) {
    List<FailedReasonDTO> reasons = msg.getTargets().stream().map(target -> {
      P2PMessage pm = new P2PMessage();
      pm.setId(RandomStringUtils.uniqueRandom());
      pm.setFrom(msg.getFrom());
      pm.setTarget(target);
      pm.setContent(msg.getContent());
      return pm;
    }).map(p -> {
      StatusCode code = messageService.dispatch(p);
      FailedReasonDTO dto = new FailedReasonDTO();
      dto.setKey(p.getTarget());
      dto.setDetail(code.toBaseResult());
      return dto;
    }).filter(r -> !r.getDetail().isSuccess()).collect(Collectors.toList());

    return new CollectionResult<>(reasons);
  }

}
